#include "Ui.h"
#include <vector>
#include <iostream>


Ui :: Ui(Database * db,Enviroment * env)
: inpt_mode(Single) , db(db) , env(env) , autocomp(0) ,autocomp_sel(-1)
{
	initscr();
	raw();
	keypad(stdscr, TRUE);
	noecho();
	inpt_win = newwin(1,COLS-1,LINES-1,0);
	outpt_win = newwin(LINES-2,COLS-1,0,0);
	outpt_fld = "Hello Vash World!";
	split_h = 1;
	max_inpt_h = db->getConfIntValue("Vash","key == \"max_inpt_h\"");
	max_autocomp = db->getConfIntValue("Vash","key == \"max_auto_comp\"");
}

int Ui :: drawInput()
{
/*	int size = (max_inpt_h<(int)lb.getLineCount())?max_inpt_h:lb.getLineCount();
	if(size)
	{

	}
	return size;
*/
	if(inpt_mode == Single && lb.getCurrentLineSize())
	{
		mvprintw(LINES-1,0,lb.str().c_str());
		return 1;
	}
	return 0;
}

void Ui :: drawSeperator(int inpt_size)
{
	std::string imode_str[Modes] = {"Singl","Multi","Inter"};
	mvhline((LINES-1)-inpt_size,0,ACS_HLINE,COLS-1);
	mvaddch((LINES-1)-inpt_size,COLS-(imode_str[inpt_mode].size()+2),ACS_RTEE);
	mvprintw((LINES-1)-inpt_size,COLS-(imode_str[inpt_mode].size()+1),imode_str[inpt_mode].c_str());
	mvaddch((LINES-1)-inpt_size,COLS-1,ACS_LTEE);
}

void Ui :: drawOutput(int size)
{
	mvaddch(0,0,ACS_PLUS);
}

void drawMenu(int y,int x,int h,int w,std::vector<std::string> & values,int selected,int trim)
{
	//Add overflow checks
	if( h > (int)values.size() )
		h = values.size();
	if( h > y )
		h = y;
	if(x+w > COLS)
	{
		w = COLS - x;
		if(w < 0)
			w = 0;
	}
	if(w && h)
	{
		std::string opt;
		for ( int c = 0 ; c < h ; c++ )
		{
			mvaddch(y-c,0,(c!=h-1)?ACS_LTEE:ACS_ULCORNER);
			opt = values[c].substr(trim);
			if((int)opt.size() > w)
			{
				opt = opt.substr(0,w-1);
				opt += '^';
			}
			if(c == selected)
			{
				attron(A_UNDERLINE);
				mvprintw(y-c,1,opt.c_str());
				attroff(A_UNDERLINE);
			}
			else
			{
				mvprintw(y-c,1,opt.c_str());
			}
		}
	}
}

void Ui :: drawAutocomplete(int y)
{
	if(lb.isModified())
	{
		autocomp_sel = -1;
		if(autocomp)
		{
			delete autocomp;
			autocomp = 0;
		}
		if(lb.str() != "")
		{
			autocomp = db->makeQuery("select value from StrTab where value like \""+lb.str()+"%\" and value != \""+lb.str()+"\"");
		}
	}
	if(autocomp && autocomp->at(0).second.size())
	{
		drawMenu(LINES-(y+1),0,max_autocomp,10,autocomp->at(0).second,autocomp_sel,lb.getPos());
		mvaddch(LINES-y,0,ACS_LLCORNER);
		mvaddch(LINES-y,lb.getPos(),ACS_URCORNER);
	}
}

void Ui :: display()
{
	int sep_h;
	werase(stdscr);
	sep_h = drawInput();
	drawSeperator(sep_h);
	drawOutput(LINES-(sep_h+1));
	drawAutocomplete(sep_h+1);
	move(LINES-1,lb.getPos());
}

std::string Ui :: readLine()
{
	int input;
	DispatchResults act;
	while(1)
	{
		display();
		input = getch();
		act = dispatchUiEvent(input);
		switch(act)
		{
			default:
				std::cerr << "Unhandled Input:\'"<< input << "\' = " << input << std::endl;
				return "exit";
			case ExecCmd:
			{
				std::string line = lb.str();
				lb.erase();
				return line;
			}
			case Success:
				break;
		}
	}
	return "";
}

Ui :: ~Ui()
{
	delete autocomp;
	endwin();
}